/*
 * Created on 2008-4-1
 *
 * TODO
 */
package jacky.lanlan.song.extension.struts.scope;

import jacky.lanlan.song.web.Scope;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * 存放处于 FlashScope 范围的值的容器，负责管理 Flash 值的生命周期。
 * <p>
 * 调用端在合适的地方调用 <code>countdown</code> 方法，它会自动检测自己是否超过 FlashScope 所规定的范围，当超过的时候，它将自我销毁。
 * 
 * @see jacky.lanlan.song.web.Scope.Flash
 * @author Jacky.Song
 */
public class FlashScopeContainer {

	private HttpServletRequest currentRequest;
	
	private HttpSession session;
	
	private boolean createSession;// 标识是否为请求创建了Session
	
	private String origName;
	
	private Object flashValue;

	private String idInSession;
	
	// 计数器，标记这个Flash值的生命周期还可以经历的来自同一客户端的请求次数。
	// 初始值为2，代表FlashScopeValue可以经历2次请求(不包括创建FlashScopeValue的那次请求)
	private int count=2;
	
	/**
	 * 创建一个可以自动销毁的 FlashScopeValue。
	 * 
	 * @param request
	 *          当前请求
	 * @param name
	 *          属性名
	 * @param value
	 *          属性值
	 */
	public FlashScopeContainer(HttpServletRequest request,String name,Object value) {
		session = request.getSession(false);
		// 如果这个请求没有Session，则专门为FlashScope创建一个Session
		if(session==null) {
			session=request.getSession(true);
			createSession=true;
		}

		origName = name;
		idInSession = Scope.Flash + "_" + name;// 加上Flash前缀以区别 Session 中的其他数据
		
		flashValue=value;
		
		session.setAttribute(origName, value);// Session 中设置值，这样即使Redirect，页面也可以得到value
		session.setAttribute(idInSession, this);// 把自己加到Session里
	}
	
	/**
	 * 刷新Request，让Flash值可以被保存在这个新的Request中。
	 */
	public void refreshRequest(HttpServletRequest currentRequest) {
		this.currentRequest = currentRequest;
	}
	
	/**
	 * 调用端可以调用这个方法实现 FlashScopeValue 的生命周期倒数，前2次调用，将会在Request相关的Session中 设置Flash值 ，之后的调用，会导致
	 * FlashScopeValue 被销毁，即它将不再存在于Session之中，而Flash值也将 会从Session中删除。
	 */
	public void countdown() {
		if(count>0) {
			this.currentRequest.setAttribute(origName, flashValue);
		}
		else if(count==0) {// DeadLine!
			// 如果专门为FlashScope创建了Session，销毁它
			if(createSession) {
				session.invalidate();
			}
			else {// 已存在的Session
				session.removeAttribute(origName);// 删除session中的value
				session.removeAttribute(idInSession);// 然后删除自己
			}
		}
		count--;
	}
	
}
